var web = web || {};
web.ImageZoom = Class.create(); 
web.ImageZoom.prototype = {
	initialize: function(options) {
		var _this = this;
		this.settings = $.extend({
			padID: null,
			panelID: null,
			cacheID: 'div-image-zoom-cache',
			type: 'standard', //standard|reverse
			zoomWith: 300,
			ZoomHight: 300,
			getZoomImgCallback: function(){},
			onZoomPanelShow: function(){}
		}, options);
		
		var types = ['standard', 'reverse'];
		if ($.inArray($.trim(this.settings.type), types) < 0) {
				this.settings.type = 'standard';
		}
		
		this.isIE6 = ($.browser.msie && $.browser.version < 7);
		this.isReverse = (this.settings.type == 'reverse');
		this.padSize = {};
		this.padOffset = null;
		this.padPosLimt = {};
		this.pupHalfSize = {};
		this.pupBorderWidth = {};
		this.zoomRate = {};
		this.scale = {};
		this.isImgLoaded = false;
		
		this.pad = null;
		this.panel = null;
		this.reverseImg = null;
		this.pZoomIcon = null;
		this.cache = null;
		this.padPup = null;
		this.lens = null;
		this.lensImg = null;
		this.lensLoading = null;
		
		this._init();
	},
	_init: function() {
		var _this = this;
		if (this.settings.padID == null || this.settings.panelID == null) return;
		
		this.pad = $('#'+ this.settings.padID);
		this.panel = $('#'+ this.settings.panelID);
		if (0 == this.pad.size() || 0 == this.panel.size()) return;
	
		this.padPup = $('<div class="izp-pup"></div>')
		this.lens = this.panel.find('.izp-lens-view');
		this.lensImg =  this.lens.children('.izp-img');
		this.lensLoading = this.lens.children('.izp-loading');
		this.pZoomIcon = this.pad.children('.izp-zoom-icon');
		
		this.padOffset = this.pad.offset();
		this.padSize.w = this.pad.width();
		this.padSize.h = this.pad.height();
		this.lens.css({width: this.settings.zoomWith, height: this.settings.ZoomHight});
		this.pad.append(this.padPup);
		
		var l = this.padOffset.left + this.pad.outerWidth(true) + 5;
		var t = this.padOffset.top;
		this.panel.css({left: l, top: t});
				
		this.cache = $('#'+ this.settings.cacheID);
		if (0 == this.cache.size()) {
			this.cache = $('<div id="'+ this.settings.cacheID +'" class="image-zoom-cache"></div>');
			$('body').append(this.cache);
		}
		this.cache.hide();
		
		this.pad.bind({
			mouseenter: function(){_this._showZoom();},
			mousemove: function(e){_this._padMove(e);},
			mouseleave: function(){_this._hideZoom();}
		});
	},
	_padMove: function(e) {
		if (!this.isImgLoaded) return;
		var x = e.pageX - this.padOffset.left - this.pupHalfSize.w;
		var y = e.pageY - this.padOffset.top - this.pupHalfSize.h;
				
		if (x < 0) x = 0;
		if (y < 0) y = 0;
		if (x > this.padPosLimt.l) x = this.padPosLimt.l;
		if (y > this.padPosLimt.t) y = this.padPosLimt.t;
		
		var l = -parseInt(x * this.scale.w);
		var t = -parseInt(y * this.scale.h);
		
		this.padPup.css({left: x, top: y});
		this.lensImg.css({left: l, top: t});
		
		if (this.isReverse ) {
			x += this.pupBorderWidth.l;
			y += this.pupBorderWidth.t;
			this.reverseImg.css({left: -x, top: -y});
		}
		return false;
	},
	_showZoom: function() {
		this.isImgLoaded = false;
		this._showZoomPanel();
		this.pZoomIcon.hide();
	},
	_hideZoom: function() {
		this._hideZoomPanel();
		this._hidePup();
		this.pZoomIcon.show();
	},
	_showPup: function() {
		var _this = this;
		if (this.isReverse) {
			this.pad.addClass('image-zoom-pad-reverse');
			
			var zoom = this.settings.getZoomImgCallback.apply(this);
			if (!zoom || (0 == zoom.size())) return;
			
			this.reverseImg = this.padPup.children('img');
			if (this.reverseImg.size() == 0) {
				this.reverseImg = $('<img />');
				this.padPup.append(this.reverseImg);
			}
			
			this.reverseImg.bind('load', function(){
				_this.padPup.show();
				_this.pupBorderWidth.l = parseInt(_this.padPup.css('border-left-width'));
				_this.pupBorderWidth.t = parseInt(_this.padPup.css('border-top-width'));
			});
			this.reverseImg.attr('src', zoom.attr('src'));
		} else {
			this.padPup.show();
		}		
	},
	_hidePup: function() {
		this.padPup.hide();
		if (this.isReverse) {
			this.pad.removeClass('image-zoom-pad-reverse');
		}
	},
	_showZoomPanel: function() {
		var zoom = this.settings.getZoomImgCallback.apply(this);
		if (!zoom || (0 == zoom.size())) return;
		
		var url = zoom.attr('zoom-src');
		if (!url) return;
		
		this.settings.onZoomPanelShow.apply(this);
		var img = this._getCachedElement(url);
		if (0 == img.size()) this._cacheImage(url);
		
		if (this._isLoadFinished(img)) {
			this._showLargeImageZoom(img);
		} else {
			this._showLargeImageLoading();
		}
		this.panel.show();
	},
	_hideZoomPanel: function() {
		this.panel.hide();
	},
	_showLargeImageLoading: function() {
		this._removeLargeImage();
		this.lensLoading.show();
	},
	_showLargeImageZoom: function(img) {
		var _this = this;
		var url = img.attr('src');		
		var cur = $('<img src="'+ url +'" />')
		this._removeLargeImage();
		
		cur.bind('load', function(){
			var w = cur.width();
			var h = cur.height();
			_this.isImgLoaded = true;
			_this._showPupZoom(w, h);
		});
		
		this.lensImg.append(cur);
	},
	_removeLargeImage: function() {
		var last = this.lensImg.children('img');
		if (last.size() > 0) last.remove();
	},
	_showPupZoom: function(w, h) {
		this.zoomRate.w = w / this.settings.zoomWith;
		this.zoomRate.h = h / this.settings.ZoomHight;
		this.scale.w = w / this.padSize.w;
		this.scale.h = h / this.padSize.h;
		
		var pw = parseInt(this.padSize.w / this.zoomRate.w);
		var ph = parseInt(this.padSize.h / this.zoomRate.h);
		this.padPosLimt.l = this.padSize.w - pw;
		this.padPosLimt.t = this.padSize.h - ph;
		this.pupHalfSize.w = parseInt(pw/2) + 2;
		this.pupHalfSize.h = parseInt(ph/2) + 2;
		this.padPup.css({left: 0, top: 0, width: pw, height: ph});
		this.lensLoading.hide();
		this._showPup();
	},
	_isLoadFinished: function(el) {
		return el.attr('loaded');
	},
	_getCachedElement: function(url) {
		return this.cache.find('img[src="'+ url +'"]');
	},
	_cacheImage: function(url) {
		var _this = this;
		var img = $('<img src="'+ url +'" />');
		this.cache.append(img);
		img.bind('load', function(){
			img.attr('loaded', 'ok');
			if (_this.panel.is(':visible')) {
				_this._showLargeImageZoom(img);
			}
		})
	}
}

var web = web || {};
web.GoodsGallery = Class.create(); 
web.GoodsGallery.prototype = {
	initialize: function(options) {
		var _this = this;
		this.settings = $.extend({
			thumb: {width: 60, view: 5}
		}, options);
		
		this.timer = null;
		this.curLoadPreImg = null;
		this.selectedIndex = 0;
		this.previewMoveing = false;
		
		this.smallImgs = null;
		this.thumbMoveing = false;
		this.thumbWarpLeft = 0;
		this.maxWarpLeft = 0;
		
		this.dynamic = null;
		this.preview = null;
		this.pLoading = null;
		this.pImgView = null;
		this.thumb = null;
		this.tPrevious = null;
		this.tNext = null;
		this.tWarp = null;
		this.zoom = null;
	},
	bind: function(elem) {
		var _this = this;
		if (1 != elem.size()) return;
		
		this.dynamic = elem.children('.gg-dynamic-loaded');
		
		this.preview = elem.children('.gg-preview');
		this.pLoading = this.preview.children('.gg-loading');
		this.pImgView = this.preview.children('.gg-img-view');
		
		this.thumb = elem.children('.gg-thumb');		
		this.tPrevious = this.thumb.children('.gg-thumb-pre-warp').children('a');
		this.tNext = this.thumb.children('.gg-thumb-next-warp').children('a');
		this.tWarp = this.thumb.children('.gg-thumb-view').children('div');
		
		this._init();
	},
	_init: function() {
		var _this = this;
		this.smallImgs = this.tWarp.find('img');
		this.smallImgs.each(function(i){
			var img = $(this);
			img.bind({
				mouseover: function(){
					_this.timer = setTimeout(function(){_this._showPreview(i, img);
					return false;
				}, 300);},
				mouseout: function(){clearTimeout(_this.timer);},
				click: function(){return false;}
			});
		});
				
		var size = this.smallImgs.size();
		if (size > this.settings.thumb.view ) {
			this._initScroll(size);
		}
	},
	_initScroll: function(size) {
		var _this = this;
		this.maxWarpLeft = 0 - (size - this.settings.thumb.view) * this.settings.thumb.width;
		this.thumbWarpLeft = 0;
		this.tWarp.css({'left':this.thumbWarpLeft, 'width': this.settings.thumb.width * size});
			
		this.tPrevious.bind('click', function(){
			if (_this.tPrevious.hasClass('i-thumb-pre-disabled')) return false;
			_this._thumbScroll('left');
		});
		
		this.tNext.bind('click', function(){
			if (_this.tNext.hasClass('i-thumb-next-disabled')) return false;
			_this._thumbScroll('right');
		});
		
		this.tPrevious.show();
		this.tNext.show();
	},
	_thumbScroll: function(direction) {
		var _this = this;
		if (this.thumbMoveing) return;
		this.thumbMoveing = true;
		
		var left = this.settings.thumb.width * 2;
		if ('right' == direction) left = 0 - left;
		this.thumbWarpLeft += left;
		
		if ('left' == direction) {
			if (this.thumbWarpLeft > 0) this.thumbWarpLeft = 0;
		} else {
			if (this.thumbWarpLeft < this.maxWarpLeft) this.thumbWarpLeft = this.maxWarpLeft;
		}
		
		this._changeButtonStatus();
		this.tWarp.animate({left: this.thumbWarpLeft}, 500, function() {
			_this.thumbMoveing = false;
		});
	},
	_changeButtonStatus: function() {
			if (this.thumbWarpLeft >= 0){
				this.tPrevious.addClass('i-thumb-pre-disabled').removeClass('i-thumb-pre');
			} else {
				if (this.tPrevious.hasClass('i-thumb-pre-disabled')) {
					this.tPrevious.addClass('i-thumb-pre').removeClass('i-thumb-pre-disabled');
				}
			}
			
			if (this.thumbWarpLeft <= this.maxWarpLeft) {
				this.tNext.addClass('i-thumb-next-disabled').removeClass('i-thumb-next');
			} else {
				if (this.tNext.hasClass('i-thumb-next-disabled')) {
					this.tNext.addClass('i-thumb-next').removeClass('i-thumb-next-disabled');
				}
			}
	},
	_showPreview: function(index, small) {
		var _this = this;
		var url = small.attr('preview-src');
		var zoomSrc = small.attr('zoom-src');
		this._smallOnSelected(index)

		if (url) {
			var id = 'goods-preview-'+ index;
			var cache = this.dynamic.children('#'+ id);
			if (0 == cache.size()) {
				cache = $('<img id="'+ id +'" index-val="'+ index +'" src="'+ url +'" zoom-src="'+ zoomSrc +'" />');
				this.dynamic.append(cache);
				this.curLoadPreImg = cache;
				this._showPreviewLoading();
				cache.bind('load', function(){
					_this._previewLoaded(cache);
				});
			} else if(1 == cache.size()) {
				this.curLoadPreImg = cache;
				if (cache.attr('loaded')) {
					this._previewLoaded(cache);
				} else {
					this._showPreviewLoading();
				}
			}
		}
	},
	_smallOnSelected: function(index) {
		var last = this.smallImgs.filter('.selected');
		var cur = this.smallImgs.eq(index);
		
		if (last.size() > 0) last.removeClass('selected');
		if (cur.size() > 0) cur.addClass('selected');
	},
	_showPreviewLoading: function(){
		this.pLoading.show();
	},
	_previewLoaded: function(img) {
		img.attr('loaded', 'ok');
		if (this.curLoadPreImg.attr('id') == img.attr('id')) {
			this.pLoading.hide();
			this._showPreviewImg(img);
		}
	},
	_showPreviewImg: function(img) {
		var _this = this;
		var last = this.pImgView.children('img');
		var lastIndex = last.attr('index-val');
		var cur = $('<img id="'+ img.attr('id') +'" index-val="'+ img.attr('index-val') +'" src="'+ img.attr('src') +'" zoom-src="'+ img.attr('zoom-src') +'" />');
		var curIndex = parseInt(img.attr('index-val'));
		if (lastIndex) lastIndex = parseInt(lastIndex)
		else lastIndex = 0;
		
		if (this.previewMoveing || lastIndex == curIndex) return;
		this.previewMoveing = true;

		if (lastIndex > curIndex) {
			last.before(cur);
			this.pImgView.css('marginTop', -350);
			this.pImgView.animate({marginTop:0}, 500, function() {
				last.remove();
				_this.previewMoveing = false;
			});
		} else {
			this.pImgView.append(cur);
			this.pImgView.animate({marginTop:-350}, 500, function() {
				last.remove();
				_this.pImgView.css('marginTop', 0);
				_this.previewMoveing = false;
			});
		}
	}
};

(function($){  
	$.fn.goodsGallery = function(options){ 
		return this.each(function(){
			new web.GoodsGallery(options).bind($(this));
		});
	}
})(jQuery); 

